/*Copyright (C) 2009 Careil Baptiste

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdio.h>
#include <string.h>
#include "Colors.h"

#ifdef WIN32
	#include <conio.h>
	#include <windows.h>
	#define DEFAULT_WIN_TXT_COL 7	//blanc foncé
	#define DEFAULT_WIN_BG_COL 0	//noir
	#define MASK_BG 0x0F
	#define MASK_TXT 0xF0
#endif

#ifdef WIN32
//fonction interne
//
//Permet de récupérer la couleur courante de la console
WORD GetCurWinCol()
{
	WORD curAttr = DEFAULT_WIN_TXT_COL | DEFAULT_WIN_BG_COL;
	CONSOLE_SCREEN_BUFFER_INFO scrBufInf;
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	if (GetConsoleScreenBufferInfo(h, &scrBufInf))
	{
		curAttr = scrBufInf.wAttributes;
	}
	return curAttr;
}
//fonction interne
//
//Permet de récupérer le code de couleur de Win32
WORD GetWinCol(CSLP_COLORTYPE color)
{
	switch (color)
	{
		case BLACK:
			return 0; break;
		case RED:
			return 4; break;
		case YELLOW:
			return 6; break;
		case GREEN:
			return 2; break;
		case BLUE:
			return 1; break;
		case VIOLET:
			return 5; break;
		case CYAN:
			return 3; break;
		case WHITE:
			return 7; break;
		default:
			return DEFAULT_WIN_TXT_COL;
	}
}
//fonction interne
//
//Permet de modifier la couleur sous Win32
void SetWinCol(WORD col)
{
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(h, col);
}
// fonction interne
//
// Permet de modifier le texte (bg = 0) ou le fond (bg = 1) de couleur
void ColorTWin(CSLP_COLORTYPE color, int bg)
{
	WORD col = 0;
	//traitement de la couleur par défaut
	if (color & DEFAULT)
	{
		col = GetCurWinCol();
		if (bg)
		{	//cas du fond
			//supprime la couleur du fond
			col &= MASK_BG;
			//ajoute la couleur du fond par défaut
			col |= DEFAULT_WIN_BG_COL;
		}
		else
		{	//cas du text
			//supprime la couleur du texte
			col &= MASK_TXT;
			//ajoute la couleur du texte par défaut
			col = DEFAULT_WIN_TXT_COL;
		}
	}
	else
	{	//couleur prédéfinie
		if (color & LIGHT)
		{
			color &= ~LIGHT;
			col = 8;
		}
		//récupération du code de la couleur
		col |= GetWinCol(color);
		//passage de la couleur au niveau background
		//si nécessaire
		if (bg)
		{
			col = col << 4;
		}
	}
	//application des couleurs
	SetWinCol(col);
}
//fonction interne
//
//Permet de colorer à la fois le fond et le texte
void ColorWin(CSLP_COLORTYPE txt, CSLP_COLORTYPE bg)
{
	WORD colTxt = 0, colBg = 0;
	//traitement du texte
	//récupération de la couleur du texte
	if (txt & DEFAULT)
	{	//couleur du texte par défaut
		colTxt = DEFAULT_WIN_TXT_COL;
	}
	else
	{	//couleur prédéfinie
		//test de luminosité
		if (txt & LIGHT)
		{
			txt &= ~LIGHT;
			colTxt |= 8;
		}
		//récupération de la valeur de la couleur
		colTxt |= GetWinCol(txt);
	}
	//traitement du fond	
	//récupération de la couleur du fond
	if (bg & DEFAULT)
	{	//couleur du fond par défaut
		colBg = DEFAULT_WIN_BG_COL;
	}
	else
	{	//couleur prédéfinie
		//test de luminosité
		if (bg & LIGHT)
		{
			bg &= ~LIGHT;
			colBg |= 8;
		}
		//récupération de la valeur de la couleur
		colBg |= GetWinCol(bg);
		//passage en couleur de fond
		colBg = colBg << 4;
	}
	//application des couleurs
	SetWinCol(colBg + colTxt);
}
#else // de ifdef WIN32
//fonction interne
//
//Permet de récupérer le code couleur unix pour le texte
char GetUnxCol(CSLP_COLORTYPE color)
{
	switch (color)
	{
		case BLACK:
			return '0'; break;
		case RED:
			return '1'; break;
		case GREEN:
			return '2'; break;
		case YELLOW:
			return '3'; break;
		case BLUE:
			return '4'; break;
		case VIOLET:
			return '5'; break;
		case CYAN:
			return '6'; break;
		case WHITE:
			return '7'; break;
		default:
			return '9';
	}
}
//fonction interne
//
//Permet de modifier les couleurs de la console sous unix
void SetUnxCol(const char* str)	
{
	//CSLP_SavePos();
	printf("\033[%sm", str);
	//CSLP_RestorePos();
}

//fonction interne
//
//Permet de colorer le text (bg = 0) ou le fond (bg = 1)
void ColorTUnx(CSLP_COLORTYPE color, int bg)
{
	int light = 0;
	char str[4];
	char colorValue;
	//permet de savoir si c'est une couleur clair ou foncée.
	if (color & LIGHT)
	{
		light = 1;
		color -= LIGHT;
	}
	//récupération de la couleur unix
	colorValue = GetUnxCol(color);
	//modifications
	if (!bg)
	{
		if (light)
		{
			str[0] = '9';
		}
		else
		{
			str[0] = '3';
		}
		str[1] = colorValue;
		str[2] = '\0';
	}
	else// of "if (!bg)"
	{
		if (light)
		{
			str[0] = '1';
			str[1] = '0';
			str[2] = colorValue;
		}
		else
		{
			str[0] = '4';
			str[1] = colorValue;
			str[2] = '\0';
		}
	}
	str[3] = '\0';
	//application de la couleur
	SetUnxCol(str);
}
//fonction interne
//
//modification simultanée du fond et du texte
void ColorUnx(CSLP_COLORTYPE txt, CSLP_COLORTYPE bg)
{
	ColorTUnx(txt, 0);
	ColorTUnx(bg, 1);
}
#endif

//fonction externe
///////////////////////////////////////////////////////////
/// Permet de réinitialiser les couleurs par défaut de la console
///////////////////////////////////////////////////////////
void DLL_IMPEXP CSLP_ResetColors()
{
	#ifdef WIN32
	SetWinCol(DEFAULT_WIN_TXT_COL);
	#else
	SetUnxCol("0");
	#endif
}

//fonction externe
///////////////////////////////////////////////////////////
/// Permet d'initialiser la couleur de texte de la console
///////////////////////////////////////////////////////////
void DLL_IMPEXP CSLP_ColorText(CSLP_COLORTYPE color)
{
	#ifdef WIN32
	ColorTWin(color, 0);
	#else
	CSLP_ResetColors();
	ColorTUnx(color, 0);
	#endif
}

//fonction externe
///////////////////////////////////////////////////////////
/// Permet d'initialiser la couleur de fond de la console
///////////////////////////////////////////////////////////
void DLL_IMPEXP CSLP_ColorBG(CSLP_COLORTYPE color)
{
	#ifdef WIN32
	ColorTWin(color, 1);
	#else
	CSLP_ResetColors();
	ColorTUnx(color, 1);
	#endif
}

//fonction externe
///////////////////////////////////////////////////////////
/// Permet l'initialisation de la couleur du fond de la console et du texte
///////////////////////////////////////////////////////////
void DLL_IMPEXP CSLP_Color(CSLP_COLORTYPE txt, CSLP_COLORTYPE bg)
{
	#ifdef WIN32
	ColorWin(txt, bg);
	#else
	ColorUnx(txt, bg);
	#endif
}


